/*
 * Copyright 2011-2012 OpenAjax Alliance
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

Components.utils.import("resource://oaa-cache-inspector/cache-inspector-common.js");
Components.utils.import("resource://gre/modules/FileUtils.jsm");
Components.utils.import("resource://gre/modules/NetUtil.jsm");


/**
 * @file sidebar-rule-result-summary.js
 *
 * @desc Supports the sidebar showing rule summary information for a list if cache items 
 */

/* ---------------------------------------------------------------- */
/*            OAA_CI and OAA_CI.RuleResultView Object             */ 
/* ---------------------------------------------------------------- */

if (typeof OAA_CI === "undefined") {
  var OAA_CI = {};
}

if (typeof OAA_CI.RuleResultView === "undefined") {
  OAA_CI.RuleResultView = {};
}


/* ---------------------------------------------------------------- */
/*       Rule Category Cache Item Views and View Controllers        */ 
/* ---------------------------------------------------------------- */

/**
 * @function OAA_CI.RuleResultView.init
 *
 * @desc Initializes the view
 */
 
OAA_CI.RuleResultView.init = function () {

  var doc = window.document;
  
  this.nls_strings               = doc.getElementById('ID_STRINGBUNDLE_LIST');
  
  this.vbox_rule_result        = doc.getElementById('ID_VBOX_RULE_RESULT_VIEW');
  
  this.label_node_result_selected        = doc.getElementById('ID_LABEL_RULE_RESULT_SELECTED');
  this.tree_node_result_details          = doc.getElementById('ID_TREE_RULE_RESULT_LIST');
  
  this.button_element_info          = doc.getElementById('ID_BUTTON_ELEMENT_RESULT_VIEW_SHOW_ELEMENT');  
   
  this.visible_tree_items = []; 
  
  this.node_results = [];
  this.node_result  = null;
    
};

/**
 * @function OAA_CI.RuleResultView.hide
 *
 * @desc Hides the element view controls
 */
 
OAA_CI.RuleResultView.hide = function () {

  this.vbox_rule_result.hidden = true;
  
};


/**
 * @function OAA_CI.RuleResultView.show
 *
 * @desc Shows the element view controls
 */
 
OAA_CI.RuleResultView.show = function () {

  this.vbox_rule_result.hidden = false;
  
};


/* ---------------------------------------------------------------- */
/*               Element Result View Functions                      */ 
/* ---------------------------------------------------------------- */

/**
 * @function OAA_CI.RuleResultView.clear
 *
 * @desc Clears the node results from the tree
 */
 
OAA_CI.RuleResultView.clear = function () {


  var nls_strings = this.nls_strings;

  this.visible_tree_items = [];          

  var row = { level : 0,
              container : false,
              open : false,
            
              message : nls_strings.getString('selectRule'),
              message_prop : 'message'
            };
  
  this.visible_tree_items.push(row);               
  
  this.setView();

  this.node_results = [];
  this.node_result  = null;
    
  OAA_CI.RuleResultView.elementButtonClear();  
  OAA_CI.turnOffHighlighting();
  
};

/**
 * @function OAA_CI.RuleResultView.update
 *
 * @desc Shows the node results of a cache item
 *
 * @param {FilteredRuleResult}  filtered_rule_result  - filtered rule result object
 */
 
OAA_CI.RuleResultView.update = function (filtered_rule_result, position) {

  function getFilteredElementCount(count) {
    var str = "";
    
    if (count === 1) str = count + " " + nls_strings.getString("filteredItem");
    else str = count + " " + nls_strings.getString("filteredItems");
         
    return str;
  }

  var SEVERITY = OpenAjax.a11y.SEVERITY;

  var nls_strings  = this.nls_strings;
  var tree         = this.tree_node_result_details;
  var label        = this.label_node_result_selected;

  this.filtered_rule_result = filtered_rule_result;
  this.rule_result = filtered_rule_result.rule_result;
  this.node_results = filtered_rule_result.filtered_node_results;

  OAA_WEB_ACCESSIBILITY_LOGGING.logger.log.debug("Rule Result View: "  + this.rule_result.getRuleSummary());

  if (this.node_results.length > 0) {
  
    this.visible_tree_items = filtered_rule_result.createListOfNodeResults(nls_strings);
    
  } 
  else {    
  
    this.visible_tree_items = [];          

    var row = { level : 0,
                container : false,
                open : false,
            
                message : 'none',
                message_prop : 'message'
              };
  
    if (filtered_rule_result.node_results_filtered_out) row.message = getFilteredElementCount(this.filtered_rule_result.node_results_filtered_out)    
    else row.message = nls_strings.getString('noRuleResults');    

    this.visible_tree_items.push(row);               

  }  

  this.setView();

  OAA_CI.RuleResultView.elementButtonClear();
  
};


/**
 * @function OAA_CI.RuleResultView.setView
 *
 * @desc Shows the node results in a custom tree view
 */
 
OAA_CI.RuleResultView.setView = function () {

  function getVisibleData(all_data) {
    var v_data = [];
         
    for (var i = 0; i < all_data.length; i++) {
         
      var d = all_data[i];
         
      v_data.push(d);
           
      if (d.open) {
           
        for (var j = 0; j < d.properties.length; j++) {
          var p = d.properties[j];
          v_data.push(p);
        }
      }         
    }
         
    return v_data;
  }

  var SEVERITY = OpenAjax.a11y.SEVERITY;

  var tree  = this.tree_node_result_details;

//  OAA_WEB_ACCESSIBILITY_LOGGING.logger.log.debug("Update Node Results Tree View: " + this.visible_tree_items.length);

  var visible_data = getVisibleData(this.visible_tree_items);
      
  var treeView = {
    visibleData : visible_data,      
        
    selection   : null,
    treeBox     : null,
 
    isSeparator: function(row){ return false; },
    isSorted: function(){ return false; },
    getImageSrc: function(row,col){ return null; },        
    getRowProperties: function(row,props){},

    setTree     : function(treeBox) { 
      this.treeBox = treeBox; 
    },
        
    get rowCount() { 
      return this.visibleData.length;
    },
        
    getCellText : function(row,column) {
      var item  = this.visibleData[row];

      switch (column.id) {
       
      case "ID_TREECOL_RULE_RESULT_PROPERTIES":       
        if (typeof item.element === 'string') return item.element;
        if (typeof item.property_name === 'string') return item.property_name;
        break;
       
      case "ID_TREECOL_RULE_RESULT":
        if (typeof item.result   === 'string') return item.result;
        if (typeof item.value    === 'string') return item.value;
        if (typeof item.message  === 'string') return item.message;
        break;
              
      default:
        break;
      }  

      return "";
    },
        
    isContainer: function(row) { 

      var item  = this.visibleData[row];
          
      if (typeof item.container === 'boolean') return item.container; 
        return false;           
    },
        
    isContainerEmpty: function(row){ 
      return false;           
    },
        
    isContainerOpen: function(row){ 
      var item  = this.visibleData[row];
          
      if (typeof item.open === 'boolean') return item.open; 

      return false;           
    },
        
    getParentIndex: function(row) {
        
      if (!this.isContainer(row)) {
        for (var t = row - 1; t >= 0 ; t--) {
          if (this.isContainer(t)) return t;
        }
      }
          
      return -1;
    },
        
    toggleOpenState: function(row){ 

      var item = this.visibleData[row];

      if (!item.container) return;

      if (item.open) {
        item.open = false;
 
        var thisLevel = this.getLevel(row);
        var deletecount = 0;
        for (var t = row + 1; t < this.visibleData.length; t++) {
          if (this.getLevel(t) > thisLevel) deletecount++;
          else break;
        }

        if (deletecount) {
          this.visibleData.splice(row + 1, deletecount);
          this.treeBox.rowCountChanged(row + 1, -deletecount);
        }
      }
      else {
        item.open = true;
      
        var prop_len = item.properties.length;

        for (var i = 0; i < prop_len; i++) {
          this.visibleData.splice(row + i + 1, 0, item.properties[i]);
        }
      
        this.treeBox.rowCountChanged(row + 1, prop_len);
      }
         
      this.treeBox.invalidateRow(row);
  
    },
       
    getLevel: function(row){ 
        
      var item  = this.visibleData[row];
          
      if (typeof item.level === 'number') return item.level; 
          
      return 0; 
    },
        
    getCellProperties: function(row,column,props) {

      var item  = this.visibleData[row];
      var property_value = "";

      switch (column.id) {
       
      case "ID_TREECOL_RULE_RESULT":
        if (typeof item.result_prop        === 'string') property_value = item.result_prop;
        if (typeof item.property_name_prop === 'string') property_value = item.property_name_prop;
        break;
       
      case "ID_TREECOL_RULE_RESULT_PROPERTIES":       
        if (typeof item.element_prop  === 'string') property_value = item.element_prop;
        if (typeof item.value_prop    === 'string')  property_value = item.value_prop;
        if (typeof item.filtered_prop === 'string')  property_value = item.filtered_prop;
        break;
       
      default:
        break;
      }  

      if (property_value !== "") {
        var aserv=Components.classes["@mozilla.org/atom-service;1"].getService(Components.interfaces.nsIAtomService);
        props.AppendElement(aserv.getAtom(property_value));
      }
     
    },
        
    getColumnProperties: function(colid,col,props) {}
 };
      
  tree.view = treeView;

  OAA_CI.highlightNodeResults(OAA_CI.ruleset.doc, this.node_results);
  
};

/**
 * @function OAA_CI.RuleResultView.sortNodeResultList
 *
 * @desc Sorts the list of rules by a sort property
 */
 
OAA_CI.RuleResultView.sortNodeResultList = function (column) {

  OAA_WEB_ACCESSIBILITY_LOGGING.logger.log.debug("Sort Node Result List: " + column.id);

  var tree = OAA_CI.RuleResultView.tree_node_result_details;

  var column_name;
  var order = tree.getAttribute("sortDirection") == "ascending" ? 1 : -1;
  
  //if the column is passed and it's already sorted by that column, reverse sort
  if (column) {
    column_name = column.id;

    if (tree.getAttribute("sortResource") == column_name) {
      order *= -1;
    }
  } else {
    column_name = tree.getAttribute("sortResource");
  }

  //setting these will make the sort option persist
  tree.setAttribute("sortDirection", order == 1 ? "ascending" : "descending");
  tree.setAttribute("sortResource", column_name);
  
  //set the appropriate attributes to show to indicator
  var cols = tree.getElementsByTagName("treecol");

  for (var i = 0; i < cols.length; i++) {
    cols[i].removeAttribute("sortDirection");
  }

  document.getElementById(column_name).setAttribute("sortDirection", order == 1 ? "ascending" : "descending");

  switch (column.id) {
       
  case "ID_TREECOL_RULE_RESULT_PROPERTIES":
    OAA_CI.RuleResultView.filtered_rule_result.sortListOfNodeResults('element', order);
    break;
       
  case "ID_TREECOL_RULE_RESULT":       
    OAA_CI.RuleResultView.filtered_rule_result.sortListOfNodeResults('severity', order);
    break;
              
  default:
    break;
  }  
  
  OAA_CI.RuleResultView.setView();

};

/**
 * @function OAA_CI.RuleResultView.nodeResultListOnSelect
 *
 * @desc Updates cache item information button when a cache item is selected
 */
 
OAA_CI.RuleResultView.onSelect = function () {

  var nls_strings  = OAA_CI.RuleResultView.nls_string;
  var tree         = OAA_CI.RuleResultView.tree_node_result_details;

  if (tree) {
  
    var index = tree.currentIndex;
    
    if (index < 0) return;
    
    var node_result = OAA_CI.RuleResultView.visible_tree_items[index].node_result;
 
    OAA_WEB_ACCESSIBILITY_LOGGING.logger.log.debug("Rule Result onSelect: " + index + " Node result: " + node_result);  

    if (typeof node_result != 'object') {
      OAA_CI.RuleResultView.node_result = null;
      OAA_CI.RuleResultView.elementButtonClear(); 
    }
    else {    
      OAA_CI.RuleResultView.node_result = node_result;
      OAA_CI.RuleResultView.elementButtonUpdate(node_result, (index + 1)); 
    }   
  }
};

/**
 * @function OAA_CI.RuleResultView.showNodeResultInformation
 *
 * @desc Show information about the currently selected element 
 */
 
OAA_CI.RuleResultView.showNodeResultInformation = function () {

  if (this.node_result) {
    OAA_CI.showRulePropertiesDialog(this.node_result);
  }  

};

/* ---------------------------------------------------------------- */
/*                 element Information Button                       */ 
/* ---------------------------------------------------------------- */

/**
 * @function OAA_CI.RuleResultView.elementButtonClear
 *
 * @desc Clears the rules in the rules tabs
 */
 
OAA_CI.RuleResultView.elementButtonClear = function () {

  if (this.nls_strings && this.button_element_info) {
    this.button_element_info.setAttribute("label", this.nls_strings.getString('element') + ' ' + this.nls_strings.getString('information'));
    this.button_element_info.setAttribute('tooltiptext', this.nls_strings.getString('noElementSelected'));
    this.button_element_info.setAttribute("disabled",    "true");
  }
  
  if (OAA_CI.cache_item_properties_dialog && 
      OAA_CI.cache_item_properties_dialog.cache_item_properties) {
    OAA_CI.cache_item_properties_dialog.cache_item_properties.clear();
  }

  this.node_result = null;

};

/**
 * @function OAA_CI.RuleResultView.elementButtonUpdate
 *
 * @desc Updates the label of the show rule information button
 *
 * @param {NodeResult}  node_result  - Node result object    
 */
 
OAA_CI.RuleResultView.elementButtonUpdate = function (node_result, position) {

  var label;

  if (this.nls_strings && this.button_element_info) {
  
    this.node_result = node_result;
    
    if (node_result.getRuleSummary && node_result.cache_item) {
    
      label = this.nls_strings.getString('moreInformationElement') + ": " + node_result.getRuleSummary();

      this.button_element_info.setAttribute("label", this.nls_strings.getString('element') + ' ' + position + ' ' + this.nls_strings.getString('information'));
      this.button_element_info.setAttribute("tooltiptext",  label);
      this.button_element_info.setAttribute("disabled", "false");

      if (OAA_CI.cache_item_properties_dialog && 
          OAA_CI.cache_item_properties_dialog.cache_item_properties) {
        OAA_CI.cache_item_properties_dialog.cache_item_properties.update(node_result.cache_item);
      }

      OAA_CI.highlightNodeResults(OAA_CI.ruleset.doc, node_result);


    }
    else {

      label = this.nls_strings.getString('noElementSelected');

      this.button_element_info.setAttribute("label", this.nls_strings.getString('element') + ' ' + this.nls_strings.getString('information'));
      this.button_element_info.setAttribute("tooltiptext",  label);
      this.button_element_info.setAttribute("disabled", "true");
      
      if (OAA_CI.cache_item_properties_dialog && 
          OAA_CI.cache_item_properties_dialog.cache_item_properties) {
        OAA_CI.cache_item_properties_dialog.cache_item_properties.clear();
      }

      OAA_CI.turnOffHighlighting();
      
    } 
  }  
};

/**
 * @function OAA_CI.RuleResultView.showCacheItemInformation
 *
 * @desc Show information about the currently selected element 
 */
 
OAA_CI.RuleResultView.showCacheItemInformation = function () {

//  OAA_WEB_ACCESSIBILITY_LOGGING.logger.log.debug("Node Result Information: " + OAA_CI.RuleResultView.node_result);

  var node_result = OAA_CI.RuleResultView.node_result;

  if (node_result) {
  
    var cache_item = node_result.cache_item;
  
    if (cache_item && 
        (!OAA_CI.cache_item_properties_dialog || 
         !OAA_CI.cache_item_properties_dialog.cache_item_properties)) {
      OAA_CI.showCacheItemPropertiesDialog(cache_item);
    }
  } 
  else {
    OAA_CI_UTILS.preferencesDialog();
  }  

};
